package com.jiawei.config;

import com.jiawei.util.JwtUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @author : willian fu
 * @date : 2019/12/12
 */
@Slf4j
@Component
public class LoginInterceptor implements HandlerInterceptor {

    @Value("${customize.token}")
    private String header;

    @Value("${customize.expires}")
    private Long expires;

    @Autowired
    private JwtUtil jwtUtil;

    /**
     * 拦截请求
     *
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //处理登录验证,从请求中取出token
        String token = request.getHeader(this.header);
        if (!StringUtils.isEmpty(token) && jwtUtil.jwtVerify(token)) {
            log.info("登录校验成功");
            return true;
        }else if (request.getMethod().equals(RequestMethod.OPTIONS.name())){
            return true;
        }else {
            response.setCharacterEncoding("utf-8");
            response.setStatus(HttpStatus.UNAUTHORIZED.value());
            response.getWriter().write("无法访问，请先登录");
            log.error("登录校验失败，访问 {} 被拦截", request.getRequestURI());
            return false;
        }
    }

    /**
     * 拦截响应，做token续期，异常拦截处理
     *
     * @param request
     * @param response
     * @param handler
     * @param ex
     * @throws Exception
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        //拦截响应，校验时间，token自动续期，token如果剩余时长小于40%，则更新token
        String token = request.getHeader(this.header);
        Long expires = jwtUtil.getTokenExpires(token);
        if (!StringUtils.isEmpty(token) && expires > 0 && expires < this.expires * 4 / 10){
            //将token设置到响应头 key = Authenticate
            response.setHeader(header, jwtUtil.jwtRefreshToken());
            //设置允许客户端读取响应头字段
            response.setHeader("Access-Control-Expose-Headers", header);
        }
        //修正错误信息
        if (response.getStatus() == HttpStatus.INTERNAL_SERVER_ERROR.value()){
            response.setCharacterEncoding("utf-8");
            response.setStatus(HttpStatus.UNAUTHORIZED.value());
            response.getWriter().write("服务器出现一点小错误");
            //response.sendError(HttpStatus.INTERNAL_SERVER_ERROR.value(), "服务器出现一点小错误");
        }
    }
}
